#include "Renderer_PCH.h"
#include "PostprocessMgr.h"

/*--------------------------------------------------------------------------*/

PostprocessMgr::PostprocessMgr() :
	m_ppmaterial(NULL),
	m_dsmaterial(NULL),
	m_sunLightEnabled(false),
	m_deferredShadingEnabled(false)
{

}

/*--------------------------------------------------------------------------*/

PostprocessMgr::~PostprocessMgr()
{

}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::InitPostprocessMgr()
{
	m_sunLight_Direction	= (glm::vec4*) g_Renderer->GetRendererStorageMgr()->CreateConst("SunLight_Direction",	EConst::Float4, 1, NULL, 0)->GetPointer();
	m_sunLight_Color		= (glm::vec4*) g_Renderer->GetRendererStorageMgr()->CreateConst("SunLight_Color",		EConst::Float4, 1, NULL, 0)->GetPointer();
	
	m_fogMinDist			= (float*) g_Renderer->GetRendererStorageMgr()->CreateConst("Fog_DistanceMin", EConst::Float1, 1, NULL, 0)->GetPointer();
	m_fogMaxDist			= (float*) g_Renderer->GetRendererStorageMgr()->CreateConst("Fog_DistanceMax", EConst::Float1, 1, NULL, 0)->GetPointer();

	SetSunLight(true, &glm::vec4(0.5f, 1.0f, 0.5f, 1.0f), &glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));

	*m_fogMinDist = 4000.f;
	*m_fogMaxDist = 6000.0f;
	SetFog(true);
}

/*--------------------------------------------------------------------------*/

bool PostprocessMgr::DeferredShadingEnabled() const
{
	return m_deferredShadingEnabled;
}

/*--------------------------------------------------------------------------*/

bool PostprocessMgr::SunLightEnabled() const
{
	return m_sunLightEnabled;
}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::SetMaterial()
{
	if (m_ppmaterial == NULL)
	{
		m_ppmaterial = g_Renderer->GetRendererStorageMgr()->GetMaterial("postprocess_generic");
	}

	if (m_shaderNeedsRebuild)
	{
		RebuildShader();
	}

	g_Renderer->BindMaterial(m_ppmaterial);

	std::string pp;
	pp += SunLightEnabled() ? "sun_" : "____";
	pp += DeferredShadingEnabled() ? "ds_" : "___";
	pp += FogEnabled() ? "fog_" : "____";

	g_UserInterface->AddMessage(pp);

	if (g_Input->GetKeyState(SDLK_F2))	SetSunLight(!SunLightEnabled());
	if (g_Input->GetKeyState(SDLK_F3))	SetDeferredShading(!DeferredShadingEnabled());
	if (g_Input->GetKeyState(SDLK_F4))	SetFog(!FogEnabled());

}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::RebuildShader()
{
	if (m_ppmaterial == NULL)
	{
		m_ppmaterial = g_Renderer->GetRendererStorageMgr()->GetMaterial("postprocess_generic");
	}

	m_ppmaterial->m_samplers.clear();

	m_ppmaterial->m_samplers.push_back(RSampler(	"CLR", 
												g_Renderer->GetRendererStorageMgr()->GetSamplerState("default"), 
												g_Renderer->GetRendererStorageMgr()->GetTexture("CLR"),
												-1));

	m_ppmaterial->m_samplers.push_back(RSampler(	"NRM", 
												g_Renderer->GetRendererStorageMgr()->GetSamplerState("default"), 
												g_Renderer->GetRendererStorageMgr()->GetTexture("NRM"),
												-1));

	m_ppmaterial->m_samplers.push_back(RSampler(	"DPT", 
												g_Renderer->GetRendererStorageMgr()->GetSamplerState("default"), 
												g_Renderer ->GetRendererStorageMgr()->GetTexture("DPT"),
												-1));

	m_ppmaterial->m_samplers.push_back(RSampler(	"FAR", 
												g_Renderer->GetRendererStorageMgr()->GetSamplerState("default"), 
												g_Renderer ->GetRendererStorageMgr()->GetTexture("FAR"),
												-1));


	/*--------------------------------------------------------------------------*/

	m_ppmaterial->m_macros.clear();

	if (m_sunLightEnabled)
	{
		m_ppmaterial->m_macros.push_back(RMacro("USE_SUNLIGHT", "1"));
	}

	if (m_deferredShadingEnabled)
	{
		m_ppmaterial->m_macros.push_back(RMacro("USE_DS", "1"));
	}

	if (m_fogEnabled)
	{
		m_ppmaterial->m_macros.push_back(RMacro("USE_FOG", "1"));
		m_ppmaterial->m_macros.push_back(RMacro("USE_UNIFORM_CAMERAFAR", "1"));
		m_ppmaterial->m_macros.push_back(RMacro("USE_UNIFORM_CAMERANEAR", "1"));
	}

// 	if (desc.m_flags & EMaterialDesc::UseFog)
// 	{
// 		material->m_macros.push_back(RMacro("USE_FOG", "1"));
// 
// 		material->m_constsValue.push_back(RConstantValue(EEngineUniform::Fog_DistanceMax_1f, (void*) &desc.m_Fog_DistanceMax));
// 		material->m_constsValue.push_back(RConstantValue(EEngineUniform::Fog_DistanceMin_1f, (void*) &desc.m_Fog_DistanceMin));
// 	}

	m_ppmaterial->CreateProgram(m_ppmaterial->m_vCode, m_ppmaterial->m_gCode, m_ppmaterial->m_fCode);
	m_shaderNeedsRebuild = false;
}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::SetDeferredShading( bool b )
{
	if (m_deferredShadingEnabled != b)
	{
		m_deferredShadingEnabled = b;
		m_shaderNeedsRebuild = true;
	}
}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::SetSunLight( bool b, const glm::vec4* dir, const glm::vec4* col )
{
	if (m_sunLightEnabled != b)
	{
		m_sunLightEnabled = b;
		m_shaderNeedsRebuild = true;
	}

	if (dir)
	{
		*m_sunLight_Direction = glm::normalize(*dir);
	}

	if (col)
	{
		*m_sunLight_Color = *col;
	}
}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::SetFog( bool b, const float* minDist, const float* maxDist )
{
	if (m_fogEnabled != b)
	{
		m_fogEnabled = b;
		m_shaderNeedsRebuild = true;
	}

	if (m_fogEnabled)
	{
		if (minDist)
			*m_fogMinDist = *minDist;
		
		if (maxDist)
			*m_fogMaxDist = *maxDist;
	}
}

/*--------------------------------------------------------------------------*/

bool PostprocessMgr::FogEnabled() const
{
	return m_fogEnabled;
}

/*--------------------------------------------------------------------------*/

void PostprocessMgr::SetDSMaterial()
{
	if (m_dsmaterial == NULL)
	{
		m_dsmaterial = g_Renderer->GetRendererStorageMgr()->GetMaterial("postprocess_ds");
	}

	g_Renderer->BindMaterial(m_dsmaterial);
}

/*--------------------------------------------------------------------------*/
